﻿
Imports osi.root.connector
Imports osi.root.formation
Imports osi.root.utils
Imports osi.root.procedure
Imports osi.service.convertor

Public Class target_questioner
    Private ReadOnly name() As Byte
    Private ReadOnly q As questioner

    Shared Sub New()
        bind_default_bytes_conversion()
    End Sub

    Private Sub New(ByVal name() As Byte,
                    ByVal q As questioner,
                    ByVal interval As Boolean)
        assert(Not isemptyarray(name))
        Me.name = name
        If q Is Nothing Then
            Me.q = questioner.default
        Else
            Me.q = q
        End If
    End Sub

    Public Sub New(ByVal name() As Byte,
                   ByVal q As questioner)
        Me.New(copy(name), q, True)
    End Sub

    Public Sub New(ByVal name() As Byte)
        Me.New(name, Nothing)
    End Sub

    Public Shared Function ctor(Of KEY_T)(ByVal name As KEY_T,
                                          ByVal q As questioner,
                                          ByVal key_t_bytes As binder(Of Func(Of KEY_T, Byte()), 
                                                                         target_questioner)) As target_questioner
        assert(key_t_bytes.has_value())
        Return New target_questioner((+key_t_bytes)(name), q, True)
    End Function

    Public Shared Function ctor(Of KEY_T)(ByVal name As KEY_T,
                                          ByVal key_t_bytes As binder(Of Func(Of KEY_T, Byte()), 
                                                                         target_questioner)) As target_questioner
        Return ctor(name, Nothing, key_t_bytes)
    End Function

    Public Shared Function ctor(Of KEY_T)(ByVal name As KEY_T,
                                          ByVal q As questioner) As target_questioner
        Return ctor(name, q, Nothing)
    End Function

    Public Shared Function ctor(Of KEY_T)(ByVal name As KEY_T) As target_questioner
        Return ctor(name, Nothing, Nothing)
    End Function

    Public Function [get]() As questioner
        Return q
    End Function

    Public Shared Operator +(ByVal i As target_questioner) As questioner
        If i Is Nothing Then
            Return Nothing
        Else
            Return i.get()
        End If
    End Operator

    Private Function append_parameter_name(ByVal request As command) As Boolean
        If request Is Nothing OrElse
           request.has_parameter(constants.parameter.name) Then
            Return False
        Else
            request.attach(constants.parameter.name, name)
            Return True
        End If
    End Function

    Default Public ReadOnly Property question(ByVal request As command,
                                              ByVal response As command) As event_comb
        Get
            Dim ec As event_comb = Nothing
            Return New event_comb(Function() As Boolean
                                      If append_parameter_name(request) Then
                                          ec = q(request, response)
                                          Return waitfor(ec) AndAlso
                                                 goto_next()
                                      Else
                                          Return False
                                      End If
                                  End Function,
                                  Function() As Boolean
                                      Return ec.end_result() AndAlso
                                             goto_end()
                                  End Function)
        End Get
    End Property

    Default Public ReadOnly Property question(ByVal request As command,
                                              ByVal response As pointer(Of command)) As event_comb
        Get
            Dim ec As event_comb = Nothing
            Return New event_comb(Function() As Boolean
                                      If append_parameter_name(request) Then
                                          ec = q(request, response)
                                          Return waitfor(ec) AndAlso
                                                 goto_next()
                                      Else
                                          Return False
                                      End If
                                  End Function,
                                  Function() As Boolean
                                      Return ec.end_result() AndAlso
                                             goto_end()
                                  End Function)
        End Get
    End Property

    Default Public ReadOnly Property question(ByVal request As command,
                                              ByVal response As Func(Of command, Boolean)) As event_comb
        Get
            Dim ec As event_comb = Nothing
            Return New event_comb(Function() As Boolean
                                      If append_parameter_name(request) Then
                                          ec = q(request, response)
                                          Return waitfor(ec) AndAlso
                                                 goto_next()
                                      Else
                                          Return False
                                      End If
                                  End Function,
                                  Function() As Boolean
                                      Return ec.end_result() AndAlso
                                             goto_end()
                                  End Function)
        End Get
    End Property

    Default Public ReadOnly Property question(ByVal request As command,
                                              ByVal response As Func(Of Boolean)) As event_comb
        Get
            Dim ec As event_comb = Nothing
            Return New event_comb(Function() As Boolean
                                      If append_parameter_name(request) Then
                                          ec = q(request, response)
                                          Return waitfor(ec) AndAlso
                                                 goto_next()
                                      Else
                                          Return False
                                      End If
                                  End Function,
                                  Function() As Boolean
                                      Return ec.end_result() AndAlso
                                             goto_end()
                                  End Function)
        End Get
    End Property

    Default Public ReadOnly Property question(ByVal request As command) As event_comb
        Get
            Dim ec As event_comb = Nothing
            Return New event_comb(Function() As Boolean
                                      If append_parameter_name(request) Then
                                          ec = q(request)
                                          Return waitfor(ec) AndAlso
                                                 goto_next()
                                      Else
                                          Return False
                                      End If
                                  End Function,
                                  Function() As Boolean
                                      Return ec.end_result() AndAlso
                                             goto_end()
                                  End Function)
        End Get
    End Property
End Class
